package com.yugao.fintech.framework.core.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.alibaba.fastjson2.JSON;
import com.yugao.fintech.framework.assistant.core.exception.BizException;
import com.yugao.fintech.framework.core.response.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

@Slf4j
public class HttpUtils {
    private static final String FORWARDING_TARGET_URL_KEY = "targetUrl";

    /**
     * 转发请求
     * <p>
     * controller层代码例子
     * <blockquote><pre>
     *       private ThreadPoolTaskExecutor myThreadPoolTaskExecutor;
     *      {@literal @RequestMapping}(value = "/test", method = {
     *         RequestMethod.DELETE, RequestMethod.GET,
     *         RequestMethod.PUT, RequestMethod.POST
     *      })
     *      public Object forwarding(@RequestParam Map<String, Object> urlParam,
     *                               {@literal @RequestBody}(required = false)Map<String, Object> requestBody,
     *                               HttpServletRequest request) throws Exception {
     *          return HttpUtils.forwardingRequest(urlParam, requestBody, request);
     *      }
     * </pre></blockquote>
     * </p>
     *
     * @param urlParam    请求路径上参数必须携带targetUrl, 路径上所有参数都会被转发到目标url上
     * @param requestBody 请求体, 会被转发到url中
     */
    public static Object forwardingRequest(Map<String, Object> urlParam, Map<String, Object> requestBody) throws Exception {
        if (CollectionUtils.isEmpty(urlParam) || !urlParam.containsKey(FORWARDING_TARGET_URL_KEY) ||
                Objects.isNull(urlParam.get(FORWARDING_TARGET_URL_KEY))) {
            return Resp.fail("url中必须携带 " + FORWARDING_TARGET_URL_KEY + " 参数");
        }
        StringBuilder targetUrlSb = new StringBuilder(String.valueOf(urlParam.get(FORWARDING_TARGET_URL_KEY))).append("?");
        for (Map.Entry<String, Object> entry : urlParam.entrySet()) {
            targetUrlSb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        HttpServletRequest request = ServletUtils.getRequest().orElseThrow(() -> new BizException("请求失败"));
        String targetUrl = targetUrlSb.substring(0, targetUrlSb.lastIndexOf("&"));
        Method method = Arrays.stream(Method.values())
                .filter(m -> m.name().equals(request.getMethod()))
                .findFirst().orElseThrow(() -> new HttpRequestMethodNotSupportedException(request.getMethod()));
        HttpRequest httpRequest = HttpUtil.createRequest(method, targetUrl);
        if (!CollectionUtils.isEmpty(requestBody)) {
            httpRequest.body(JSON.toJSONString(requestBody));
        }
        httpRequest.headerMap(ServletUtils.getHeaders(), true);
        try (HttpResponse execute = httpRequest.execute()) {
            return JSON.parseObject(execute.body());
        } catch (Exception e) {
            log.error("转发请求失败, targetUrl: {}, method: {} ", targetUrl, request.getMethod(), e);
            return Resp.fail("请求失败");
        }
    }
}
